import random

class Interval(object):
    """The interval is a range of number from start to end"""
    def __init__(self,start,end):
        self.start=start
        self.end=end
        self.history = ['h']
        self.satisficerprob = 1.0

    def __str__(self):
        return str(self.start) + ': '+ str(self.history)

    def addBack(self,instance):
        """Add an instance (hunt/slack) to the back of interval's history"""
        if len(self.history)<10:
            self.history.append(instance)
        else:
            self.history = self.history[1:] + [instance]
        

    def computehuntprob(self):
        """Compute the huntprob for this interval"""
        
        #Compute historyprob = H/(H+S)
        historyprob = float(self.history.count('h'))/float(len(self.history))

        #Huntprob = 0.4*historyprob + 0.6*satisficerprob
        histweight = 0.4
        satweight = 1.0-histweight
        return histweight*historyprob + satweight*self.satisficerprob


    def contains(self,num):
        """Returns True if num is in the Interval"""
        return num >= self.start and num <= self.end



class Player:
    '''
    Your strategy starts here.
    '''
    def __init__(self):
        self.food = 0
        self.reputation = 0
    
        
    def hunt_choices(
                    self,
                    round_number,
                    current_food,
                    current_reputation,
                    m,
                    player_reputations,
                    ):
        '''Required function defined in the rules'''
        global intervallist
        global sortedreps
        global replist
        global numround
        global tracklist

        numround = round_number


        #Sort reputation in ascending order
        replist = player_reputations[:]
        sortedreps = player_reputations[:]
        sortedreps.sort()
        
        #Build the initial interval list in the first round
        if round_number == 1:
            intervallist = []
            numintervals = 100
            for i in range(0,numintervals):
                interval = Interval(i/numintervals,(i+1)/numintervals)
                intervallist.append(interval)
       
        #Build the decision list as required
        decisionlist = []
        for reputation in player_reputations:
            #Determine the interval that i lies in
            for interval in intervallist:
                if interval.contains(reputation):
                    
            #Compute the probability of hunting in that interval
                    huntprob = interval.computehuntprob()

            #Decide based on this probability
                    if random.random() < huntprob:
                        choice = 'h'
                    else:
                        choice = 's'
                    decisionlist.append(choice)
                    break
            
        return decisionlist

            
        
    def hunt_outcomes(self, food_earnings):
        '''Required function defined in the rules'''
        global intervallist
        global sortedreps
        global replist
        global numround
        global level

        """Factor 1: Satisficing"""

        if numround==1:
            level = 1.0


        #Define the threshold for satisficing aim.
        #Here, threshold is -1 per player
        threshold = -1*len(food_earnings)

        #Calculate total earnings:
        total = 0
        for i in food_earnings:
            total += i

        #If total earnings are not satisfactory, decrease the level
        if total < threshold and level > 0.1:
            level -= 0.1

        elif total > threshold and level < 0.9:
            level += 0.1
                    
        #Based on level, change the satisficerprob accordingly
        numhunt = int(len(intervallist)*level)
        numslack = len(intervallist) - numhunt
        for i in range(0,len(intervallist)):
            if i < numslack:
                intervallist[i].satisficerprob = 0.0
            else:
                intervallist[i].satisficerprob = 1.0

        """Factor 2: History"""

        #Build decision dict, the lessons learned for each player
        decisiondict = {}
        for i in range(0,len(replist)):
            reputation = replist[i]
            result = food_earnings[i]
            if result == 0 or result == 1:
                decision = 'h'
            else:
                decision = 's'
            decisiondict[reputation]=decision


        #Midpoints separate the players' reputations.
        #They will be partitions to help the adding of 'h' or 's' to the histories
        midpointlist = []
        for i in range(0,len(sortedreps)-1):
            midpoint = 0.5*(sortedreps[i]+sortedreps[i+1])
            midpointlist.append(midpoint)
        midpointlist.append(1.0)
        
        #For each interval, add 'h' or 's', with reference to the closest reputation
        for interval in intervallist:
            if interval.start < midpointlist[0]:
                interval.addBack(decisiondict[sortedreps[0]])
            else:
                sortedreps = sortedreps[1:]
                midpointlist = midpointlist[1:]
                interval.addBack(decisiondict[sortedreps[0]])



    def round_end(self, award, m, number_hunters):
        '''Required function defined in the rules'''
        pass

